﻿using System;

namespace UniRx.Operators
{
	// Token: 0x02000320 RID: 800
	internal class ThrottleObservable<T> : OperatorObservableBase<T>
	{
		// Token: 0x060010B4 RID: 4276 RVA: 0x0004CDB8 File Offset: 0x0004B1B8
		public ThrottleObservable(IObservable<T> source, TimeSpan dueTime, IScheduler scheduler) : base(scheduler == Scheduler.CurrentThread || source.IsRequiredSubscribeOnCurrentThread<T>())
		{
			this.source = source;
			this.dueTime = dueTime;
			this.scheduler = scheduler;
		}

		// Token: 0x060010B5 RID: 4277 RVA: 0x0004CDE9 File Offset: 0x0004B1E9
		protected override IDisposable SubscribeCore(IObserver<T> observer, IDisposable cancel)
		{
			return new ThrottleObservable<T>.Throttle(this, observer, cancel).Run();
		}

		// Token: 0x040009CD RID: 2509
		private readonly IObservable<T> source;

		// Token: 0x040009CE RID: 2510
		private readonly TimeSpan dueTime;

		// Token: 0x040009CF RID: 2511
		private readonly IScheduler scheduler;

		// Token: 0x02000321 RID: 801
		private class Throttle : OperatorObserverBase<T, T>
		{
			// Token: 0x060010B6 RID: 4278 RVA: 0x0004CDF8 File Offset: 0x0004B1F8
			public Throttle(ThrottleObservable<T> parent, IObserver<T> observer, IDisposable cancel) : base(observer, cancel)
			{
				this.parent = parent;
			}

			// Token: 0x060010B7 RID: 4279 RVA: 0x0004CE30 File Offset: 0x0004B230
			public IDisposable Run()
			{
				this.cancelable = new SerialDisposable();
				IDisposable disposable = this.parent.source.Subscribe(this);
				return StableCompositeDisposable.Create(this.cancelable, disposable);
			}

			// Token: 0x060010B8 RID: 4280 RVA: 0x0004CE68 File Offset: 0x0004B268
			private void OnNext(ulong currentid)
			{
				object obj = this.gate;
				lock (obj)
				{
					if (this.hasValue && this.id == currentid)
					{
						this.observer.OnNext(this.latestValue);
					}
					this.hasValue = false;
				}
			}

			// Token: 0x060010B9 RID: 4281 RVA: 0x0004CED0 File Offset: 0x0004B2D0
			public override void OnNext(T value)
			{
				object obj = this.gate;
				ulong currentid;
				lock (obj)
				{
					this.hasValue = true;
					this.latestValue = value;
					this.id += 1UL;
					currentid = this.id;
				}
				SingleAssignmentDisposable singleAssignmentDisposable = new SingleAssignmentDisposable();
				this.cancelable.Disposable = singleAssignmentDisposable;
				singleAssignmentDisposable.Disposable = this.parent.scheduler.Schedule(this.parent.dueTime, delegate()
				{
					this.OnNext(currentid);
				});
			}

			// Token: 0x060010BA RID: 4282 RVA: 0x0004CF7C File Offset: 0x0004B37C
			public override void OnError(Exception error)
			{
				this.cancelable.Dispose();
				object obj = this.gate;
				lock (obj)
				{
					this.hasValue = false;
					this.id += 1UL;
					try
					{
						this.observer.OnError(error);
					}
					finally
					{
						base.Dispose();
					}
				}
			}

			// Token: 0x060010BB RID: 4283 RVA: 0x0004CFFC File Offset: 0x0004B3FC
			public override void OnCompleted()
			{
				this.cancelable.Dispose();
				object obj = this.gate;
				lock (obj)
				{
					if (this.hasValue)
					{
						this.observer.OnNext(this.latestValue);
					}
					this.hasValue = false;
					this.id += 1UL;
					try
					{
						this.observer.OnCompleted();
					}
					finally
					{
						base.Dispose();
					}
				}
			}

			// Token: 0x040009D0 RID: 2512
			private readonly ThrottleObservable<T> parent;

			// Token: 0x040009D1 RID: 2513
			private readonly object gate = new object();

			// Token: 0x040009D2 RID: 2514
			private T latestValue = default(T);

			// Token: 0x040009D3 RID: 2515
			private bool hasValue;

			// Token: 0x040009D4 RID: 2516
			private SerialDisposable cancelable;

			// Token: 0x040009D5 RID: 2517
			private ulong id;
		}
	}
}
